package manager

import (
	"BlazeRider-backend/app/models"
	"BlazeRider-backend/config"
	"database/sql"
	"fmt"
	"sync"
)

// LiveRoomStatus 表示直播间的状态
type LiveRoomStatus struct {
	IsInGame bool
	// 可以添加其他需要的状态信息字段
}

type UserTrack struct {
	Track int
}

type LiveRoomInfo struct {
	LiveRoomId        string       `json:"live_room_id"`
	State             string       `json:"state"`
	Times             int          `json:"times"`
	AnchorOpenId      string       `json:"anchor_open_id"`
	AvatarUrl         string       `json:"avatar_url"`
	NickName          string       `json:"nick_name"`
	FailGiftPageNum   int          `json:"fail_gift_page_num"`
	FailGiftWholePage int          `json:"fail_gift_whole_page"`
	StartAt           sql.NullTime `json:"start_at"`  // 使用 NullTime
	EndAt             sql.NullTime `json:"end_at"`    // 使用 NullTime
	CreateAt          sql.NullTime `json:"create_at"` // 使用 NullTime
	UpdateAt          sql.NullTime `json:"update_at"` // 使用 NullTime
}

type LiveTrackUserInfo struct {
	LiveRoomId string       `json:"live_room_id"`
	UserId     string       `json:"user_id"`
	Times      int          `json:"times"`
	Track      int          `json:"track"`
	Job        int          `json:"job"`
	CreateAt   sql.NullTime `json:"create_at"` // 使用 NullTime
	UpdateAt   sql.NullTime `json:"update_at"` // 使用 NullTime
}

type LiveTrackWithUserInfo struct {
	LiveRoomId   string       `json:"live_room_id"`
	UserId       string       `json:"user_id"`
	Times        int          `json:"times"`
	Track        int          `json:"track"`
	Job          int          `json:"job"`
	UserName     string       `json:"user_name"`
	UserHeadImg  string       `json:"head_img"`
	UserLevel    int          `json:"level"`
	UserScore    int          `json:"score"`
	UserExpireAt sql.NullTime `json:"expire_at"`
	CreateAt     sql.NullTime `json:"create_at"` // 使用 NullTime
	UpdateAt     sql.NullTime `json:"update_at"` // 使用 NullTime
}

type GameDataInfo struct {
	LiveRoomId string       `json:"live_room_id"`
	Times      string       `json:"times"`
	RawData    string       `json:"raw_data"`
	CreateAt   sql.NullTime `json:"create_at"` // 使用 NullTime
	UpdateAt   sql.NullTime `json:"update_at"` // 使用 NullTime
}

// LiveRoomManager 管理直播间的状态
type LiveRoomManager struct {
	roomUserTrack map[string]map[string]UserTrack
	roomStatusMap map[string]LiveRoomStatus
	storage       LiveRoomMysqlStorage
	mu            sync.Mutex
}

func NewLiveRoomManager() *LiveRoomManager {
	var storage *LiveRoomMysqlStorage
	var err error
	if config.Get().Database.Enabled {
		storage, err = NewLiveRoomMysqlStorage()
		if err != nil {
			return nil
		}

		return &LiveRoomManager{
			roomStatusMap: make(map[string]LiveRoomStatus),
			storage:       *storage,
		}
	}

	return &LiveRoomManager{
		roomStatusMap: make(map[string]LiveRoomStatus),
	}
}

// SetLiveRoomStatus 设置直播间的状态
func (lrm *LiveRoomManager) SetLiveRoomStatus(liveRoomID string, isInGame bool) {
	if config.Get().Database.Enabled {
		err := lrm.storage.SetLiveRoomState(liveRoomID, isInGame)
		if err != nil {
			return
		}
	}

	lrm.mu.Lock()
	defer lrm.mu.Unlock()

	// 如果不存在，则初始化一个新的状态
	if _, exists := lrm.roomStatusMap[liveRoomID]; !exists {
		lrm.roomStatusMap[liveRoomID] = LiveRoomStatus{IsInGame: false}
	}
	// 更新状态
	lrm.roomStatusMap[liveRoomID] = LiveRoomStatus{IsInGame: isInGame}
	if isInGame == false {

	}
}

// SetLiveRoomStatus 设置直播间的状态
func (lrm *LiveRoomManager) CreateLiveRoomIfNotExist(liveRoomID, AnchorOpenId, AvatarUrl, NickName string) (string, error) {
	if config.Get().Database.Enabled {
		liveRoomID, err := lrm.storage.CreateLiveRoomIfNotExist(liveRoomID, AnchorOpenId, AvatarUrl, NickName)
		if err != nil {
			return liveRoomID, err
		}

		return liveRoomID, nil
	}

	return "", fmt.Errorf("CreateLiveRoomIfNotExist has no mem logic : ")
}

// JoinLiveRoomCamp 用户加入直播间的某个阵营
func (lrm *LiveRoomManager) JoinLiveRoomCamp(liveRoomId string, times int, state string, userId string, track int, job int) error {
	if config.Get().Database.Enabled {
		_, err := lrm.storage.JoinLiveRoomTrackMysql(liveRoomId, times, state, userId, track, job)
		if err != nil {
			return err
		}

		return nil
	}

	lrm.mu.Lock()
	defer lrm.mu.Unlock()

	// 如果不存在，则初始化一个新的状态
	if _, exists := lrm.roomUserTrack[liveRoomId][userId]; !exists {
		lrm.roomUserTrack[liveRoomId][userId] = UserTrack{Track: track}
	}

	return nil
}

// GetLiveTrackInfoByUserId 获取直播间中某个用户的加入阵营数据
func (lrm *LiveRoomManager) GetLiveTrackInfoByUserId(liveRoomID string, userId string) (*LiveTrackUserInfo, error) {
	if config.Get().Database.Enabled {
		liveTrackUserMysqlInfo, err := lrm.storage.GetLiveRoomTrackMysql(liveRoomID, userId)
		if err != nil {
			return nil, err
		}

		return &LiveTrackUserInfo{
			LiveRoomId: liveTrackUserMysqlInfo.LiveRoomId,
			UserId:     liveTrackUserMysqlInfo.UserId,
			Times:      liveTrackUserMysqlInfo.Times,
			Track:      liveTrackUserMysqlInfo.Track,
			CreateAt:   liveTrackUserMysqlInfo.CreateAt,
			UpdateAt:   liveTrackUserMysqlInfo.UpdateAt,
		}, nil // 返回 LiveRoomStatus 和 false
	}

	return nil, nil
}

// GetLiveTrackInfoByUserId 获取直播间中某个用户的加入阵营数据
func (lrm *LiveRoomManager) GetLiveTrackInfosWithUserInfoByTime(liveRoomID string, times int, timeStr string) ([]LiveTrackWithUserInfo, error) {
	var liveTrackUserInfoList []LiveTrackWithUserInfo
	if config.Get().Database.Enabled {
		liveTrackUserMysqlInfoList, err := lrm.storage.GetLiveTrackInfosWithUserInfoByTime(liveRoomID, times, timeStr)
		if err != nil {
			return nil, err
		}

		for _, recordInfo := range liveTrackUserMysqlInfoList {
			liveTrackUserInfo := LiveTrackWithUserInfo{
				LiveRoomId:   recordInfo.LiveRoomId,
				UserId:       recordInfo.UserId,
				Times:        recordInfo.Times,
				Track:        recordInfo.Track,
				Job:          recordInfo.Job,
				CreateAt:     recordInfo.CreateAt,
				UpdateAt:     recordInfo.UpdateAt,
				UserName:     recordInfo.UserName,
				UserHeadImg:  recordInfo.UserHeadImg,
				UserLevel:    recordInfo.UserLevel,
				UserScore:    recordInfo.UserScore,
				UserExpireAt: recordInfo.UserExpireAt,
			}
			liveTrackUserInfoList = append(liveTrackUserInfoList, liveTrackUserInfo)
		}
		return liveTrackUserInfoList, nil
	}

	return nil, nil
}

// GetLiveRoomStatus 获取直播间的状态, 返回的bool是true代表有错误
func (lrm *LiveRoomManager) GetLiveInfo(liveRoomID string) (*LiveRoomInfo, error) {
	if config.Get().Database.Enabled {
		liveMysqlInfo, err := lrm.storage.GetLiveRoom(liveRoomID)
		if err != nil {
			return nil, err
		}

		return &LiveRoomInfo{
			LiveRoomId:   liveMysqlInfo.LiveRoomId,
			AnchorOpenId: liveMysqlInfo.AnchorOpenId,
			AvatarUrl:    liveMysqlInfo.AvatarUrl,
			NickName:     liveMysqlInfo.NickName,
			State:        liveMysqlInfo.State,
			Times:        liveMysqlInfo.Times,
			StartAt:      liveMysqlInfo.StartAt,
			EndAt:        liveMysqlInfo.EndAt,
			CreateAt:     liveMysqlInfo.CreateAt,
			UpdateAt:     liveMysqlInfo.UpdateAt,
		}, nil // 返回 LiveRoomStatus 和 false
	}

	return nil, nil
}

// GetLiveRoomStatus 获取直播间的状态, 返回的bool是true代表有错误
func (lrm *LiveRoomManager) GetLiveTrackByUserId(liveRoomID string, userId string) (*LiveTrackUserInfo, error) {
	if config.Get().Database.Enabled {
		liveTrackUserMysqlInfo, err := lrm.storage.GetLiveRoomTrackMysql(liveRoomID, userId)
		if err != nil {
			return nil, err
		}

		return &LiveTrackUserInfo{
			LiveRoomId: liveTrackUserMysqlInfo.LiveRoomId,
			UserId:     liveTrackUserMysqlInfo.UserId,
			Times:      liveTrackUserMysqlInfo.Times,
			Track:      liveTrackUserMysqlInfo.Track,
			Job:        liveTrackUserMysqlInfo.Job,
			CreateAt:   liveTrackUserMysqlInfo.CreateAt,
			UpdateAt:   liveTrackUserMysqlInfo.UpdateAt,
		}, nil // 返回 LiveRoomStatus 和 false
	}

	return nil, fmt.Errorf("GetLiveTrackByUserId no mem logic")
}

// GetLiveRoomStatus 获取直播间的状态, 返回的bool是true代表有错误
func (lrm *LiveRoomManager) GetLiveRoomStatus(liveRoomID string) (LiveRoomStatus, bool) {
	if config.Get().Database.Enabled {
		var status LiveRoomStatus
		liveRoomInfo, err := lrm.storage.GetLiveRoom(liveRoomID)
		if err != nil {
			return status, true
		}

		if liveRoomInfo.State == "start" {
			status.IsInGame = true
		} else {
			status.IsInGame = false
		}
		return status, false // 返回 LiveRoomStatus 和 false
	}

	lrm.mu.Lock()
	defer lrm.mu.Unlock()

	// 如果不存在，则初始化一个新的状态，并返回
	if _, exists := lrm.roomStatusMap[liveRoomID]; !exists {
		lrm.roomStatusMap[liveRoomID] = LiveRoomStatus{IsInGame: false}
		return lrm.roomStatusMap[liveRoomID], false
	}
	// 返回现有的状态
	return lrm.roomStatusMap[liveRoomID], false
}

// GetLiveRoomStatus 获取直播间的状态, 返回的bool是true代表有错误
func (lrm *LiveRoomManager) BatchInsertLiveRoomResults(results []models.LiveRoomResult) error {
	if config.Get().Database.Enabled {
		var mysqlResults []LiveRoomResultMysqlInfo
		for _, result := range results {
			mysqlResults = append(mysqlResults, LiveRoomResultMysqlInfo{
				LiveRoomID:   result.LiveRoomID,
				Times:        result.Times,
				UserID:       result.UserID,
				GameScore:    result.GameScore,
				Track:        result.Track,
				Job:          result.Job,
				IsChampion:   result.IsChampion,
				IsFinish:     result.IsFinish,
				IsBiggest:    result.IsBiggest,
				GiftValue:    result.GiftValue,
				GiftScore:    result.GiftScore,
				GetScore:     result.GetScore,
				HasDone:      result.HasDone,
				UserName:     result.UserName,
				HeadImg:      result.HeadImg,
				UserLevel:    result.UserLevel,
				UserScore:    result.UserScore,
				TargetLevel:  result.TargetLevel,
				TargetScore:  result.TargetScore,
				Mileage:      result.Mileage,
				JumpHeight:   result.JumpHeight,
				FinishTime:   result.FinishTime,
				FinishTime1:  result.FinishTime1,
				FinishTime2:  result.FinishTime2,
				FastestSpeed: result.FastestSpeed,
				AttackPower:  result.AttackPower,
				ExpireAt:     result.ExpireAt,
				CreateAt:     result.CreateAt,
				UpdateAt:     result.UpdateAt,
			})
		}

		err := lrm.storage.BatchInsertLiveRoomResults(mysqlResults)
		if err != nil {
			return err
		}

		return nil // 说明处理正确
	}

	return fmt.Errorf("BatchInsertLiveRoomResults no mem logic")
}

// GetLiveRoomStatus 获取直播间的状态, 返回的bool是true代表有错误
func (lrm *LiveRoomManager) GetLiveRoomResults(liveRoomId string, times int) ([]models.LiveRoomResult, error) {
	if config.Get().Database.Enabled {
		var liveRoomResults []models.LiveRoomResult

		mysqlResults, err := lrm.storage.GetLiveRoomResults(liveRoomId, times)
		if err != nil {
			return nil, err
		}

		for _, result := range mysqlResults {
			liveRoomResults = append(liveRoomResults, models.LiveRoomResult{
				LiveRoomID:  result.LiveRoomID,
				Times:       result.Times,
				UserID:      result.UserID,
				GameScore:   result.GameScore,
				Track:       result.Track,
				IsChampion:  result.IsChampion,
				IsFinish:    result.IsFinish,
				GiftValue:   result.GiftValue,
				GiftScore:   result.GiftScore,
				GetScore:    result.GetScore,
				HasDone:     result.HasDone,
				UserName:    result.UserName,
				HeadImg:     result.HeadImg,
				UserLevel:   result.UserLevel,
				UserScore:   result.UserScore,
				TargetLevel: result.TargetLevel,
				TargetScore: result.TargetScore,
				ExpireAt:    result.ExpireAt,
				CreateAt:    result.CreateAt,
				UpdateAt:    result.UpdateAt,
			})
		}

		return liveRoomResults, nil // 说明处理正确
	}

	return nil, fmt.Errorf("GetLiveRoomResults no mem logic")
}

// GetLiveRoomResultsForGameRank 获取直播对局的用户的总排行榜数据 有子查询，执行效率低
func (lrm *LiveRoomManager) GetLiveRoomResultsForGameRank(liveRoomId string, times int) ([]models.LiveRoomResult, error) {
	if config.Get().Database.Enabled {
		var liveRoomResults []models.LiveRoomResult

		mysqlResults, err := lrm.storage.GetLiveRoomResultsForGameRank(liveRoomId, times)
		if err != nil {
			return nil, err
		}

		for _, result := range mysqlResults {
			liveRoomResults = append(liveRoomResults, models.LiveRoomResult{
				LiveRoomID:  result.LiveRoomID,
				Times:       result.Times,
				UserID:      result.UserID,
				GameScore:   result.GameScore,
				Track:       result.Track,
				IsChampion:  result.IsChampion,
				IsFinish:    result.IsFinish,
				GiftValue:   result.GiftValue,
				GiftScore:   result.GiftScore,
				GetScore:    result.GetScore,
				HasDone:     result.HasDone,
				UserName:    result.UserName,
				HeadImg:     result.HeadImg,
				UserLevel:   result.UserLevel,
				UserScore:   result.UserScore,
				TargetLevel: result.TargetLevel,
				TargetScore: result.TargetScore,
				ExpireAt:    result.ExpireAt,
				CreateAt:    result.CreateAt,
				UpdateAt:    result.UpdateAt,
				TotalRank:   result.TotalRank,
			})
		}

		return liveRoomResults, nil // 说明处理正确
	}

	return nil, fmt.Errorf("GetLiveRoomResultsForGameRank no mem logic")
}

// GetLiveRoomStatus 获取直播间的状态, 返回的bool是true代表有错误
func (lrm *LiveRoomManager) SetDoneByCreateAt(dateStr string) error {
	if config.Get().Database.Enabled {
		err := lrm.storage.SetDoneByCreateAt(dateStr)
		if err != nil {
			return err
		}

		return nil // 说明处理正确
	}

	return fmt.Errorf("SetGiftRecordLevel no mem logic")
}

func (lrm *LiveRoomManager) GetLiveRoomFailGiftInfoWhenStart() ([]LiveRoomMysqlInfo, error) {
	if config.Get().Database.Enabled {
		res, err := lrm.storage.GetLiveRoomFailGiftInfoWhenStart()
		if err != nil {
			return nil, err
		}

		return res, nil // 说明处理正确
	}

	return nil, fmt.Errorf("GetLiveRoomFailGiftInfoWhenStart no mem logic")
}

// SetLiveRoomStatus 设置直播间的状态
func (lrm *LiveRoomManager) SetLiveRoomFailGiftNum(liveRoomID string, pageNum, pageNumWhole int) error {
	if config.Get().Database.Enabled {
		err := lrm.storage.SetLiveRoomFailGiftNum(liveRoomID, pageNum, pageNumWhole)
		if err != nil {
			return err
		}
	}

	return fmt.Errorf("SetLiveRoomFailGiftNum no mem logic")
}

// SetLiveRoomStatus 设置直播间的状态
func (lrm *LiveRoomManager) SetGameData(liveRoomID string, times int, rawData string) error {
	if config.Get().Database.Enabled {
		err := lrm.storage.InsertGameDate(liveRoomID, times, rawData)
		if err != nil {
			return err
		}
		return nil
	}

	return fmt.Errorf("setGameData no mem logic")
}

// SetLiveRoomStatus 设置直播间的状态
func (lrm *LiveRoomManager) GetGameData(liveRoomID string, times int) (*GameDataInfo, error) {
	var gameData GameDataInfo
	if config.Get().Database.Enabled {
		gameDataMysql, err := lrm.storage.GetGameDate(liveRoomID, times)
		if err != nil {
			return nil, err
		}
		gameData.LiveRoomId = gameDataMysql.LiveRoomId
		gameData.Times = gameDataMysql.Times
		gameData.RawData = gameDataMysql.RawData
		gameData.CreateAt = gameDataMysql.CreateAt
		gameData.UpdateAt = gameDataMysql.UpdateAt
		return &gameData, nil
	}

	return nil, fmt.Errorf("getGameData no mem logic")
}
